package cn.banyingli.banyinglilib.tools;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;

public class FileTools {

    /**
     * sd卡是否可用
     *
     * @return
     */
    public static boolean isSdCardAvailable() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }


    /**
     * 创建根缓存目录
     *
     * @return
     */
    public static String createCacheRootPath(Context context) {
        String cacheRootPath = "";
        if (isSdCardAvailable()) {
            // /sdcard/Android/data/<application package>/cache
            cacheRootPath = context.getExternalCacheDir().getPath();
        } else {
            // /data/data/<application package>/cache
            cacheRootPath = context.getCacheDir().getPath();
        }
        return cacheRootPath;
    }

    /**
     * 创建文件夹
     *
     * @param dirPath
     * @return 创建失败返回""
     */
    public static String createDir(String dirPath) {
        try {
            File dir = new File(dirPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            return dir.getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dirPath;
    }

    /**
     * 创建文件
     * 文件路径为根路径：/storage/emulated/0/Android/data/<application package>/cache
     */
    public static boolean createCacheFile(Context context, String uniqueName) {
        File file = getDiskCacheDir(context, uniqueName);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 往文件中储存内容，根据文件路径,这个方法更严谨一些
     *
     * @param content
     * @param filePath
     * @return
     */
    public static boolean saveStringToFile(String content, String filePath) {
        if (content == null || TextUtils.isEmpty(filePath)) {
            return false;
        } else {
            File file = new File(filePath);
            PrintWriter pw = null;
            try {
                if (!file.exists()) {
                    file.createNewFile();
                }
                if (file.exists()) {
                    pw = new PrintWriter(file);
                    // pw = new PrintWriter(new BufferedWriter(
                    // new FileWriter(file)));
                    pw.write(content);
                    return true;
                } else {
                    return false;
                }
            } catch (Exception e) {
                return false;
            } finally {
                if (pw != null) {
                    pw.close();
                }
            }

        }
    }


    /**
     * 读取文件中的内容，根据文件路径
     *
     * @param filePath
     * @return
     */
    @SuppressWarnings("resource")
    public static String readStringFromFile(String filePath) {
        if (TextUtils.isEmpty(filePath)) {
            return null;
        }
        File file = new File(filePath);
        if (file.exists()) {
            try {

                StringBuffer strBuffer = new StringBuffer();
                BufferedReader reader = new BufferedReader(new FileReader(file));
                String strLine = "";
                while ((strLine = reader.readLine()) != null) {
                    strBuffer.append(strLine);
                }
                return strBuffer.toString();
            } catch (Exception e) {
                return null;
            }
        } else {
            return null;
        }
    }


    /**
     * 根据传进的 file 删除文件或者文件夹
     *
     * @param file
     */
    public static void deleteFileOrDirectory(File file) {
        try {
            if (file.isFile()) {
                file.delete();
                return;
            }
            if (file.isDirectory()) {
                File[] childFiles = file.listFiles();
                // 删除空文件夹
                if (childFiles == null || childFiles.length == 0) {
                    file.delete();
                    return;
                }
                // 递归删除文件夹下的子文件
                for (int i = 0; i < childFiles.length; i++) {
                    deleteFileOrDirectory(childFiles[i]);
                }
                file.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据传进的 filePath 删除文件或者文件夹
     *
     * @param filePath
     * @return boolean
     */
    public static boolean deleteFileOrDirectory(String filePath) {

        if (TextUtils.isEmpty(filePath)) {
            return false;
        } else {
            try {
                File file = new File(filePath);
                if (file.isFile()) {
                    file.delete();
                    return true;
                }
                if (file.isDirectory()) {
                    File[] childFiles = file.listFiles();
                    // 删除空文件夹
                    if (childFiles == null || childFiles.length == 0) {
                        file.delete();
                        return true;
                    }
                    // 递归删除文件夹下的子文件
                    for (int i = 0; i < childFiles.length; i++) {
                        deleteFileOrDirectory(childFiles[i]);
                    }
                    file.delete();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 将内容写入文件
     *
     * @param filePath eg:/mnt/sdcard/demo.txt
     * @param content  内容
     */
    public static void writeFileSdcard(String filePath, String content, boolean isAppend) {

        try {
            FileOutputStream fout = new FileOutputStream(filePath, isAppend);
            byte[] bytes = content.getBytes();

            fout.write(bytes);

            fout.close();

        } catch (Exception e) {

            e.printStackTrace();

        }
    }

    /**
     * 根据传入的文件名字，在根缓存目录下创建文件，并返回该文件对象
     *
     * @param context
     * @param uniqueName
     * @return
     */
    public static File getDiskCacheDir(Context context, String uniqueName) {
        final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ? getExternalCacheDir(context).getPath() : context.getCacheDir().getPath();
        return new File(cachePath + File.separator + uniqueName);
    }

    public static File getExternalCacheDir(Context context) {
        final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
        return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
    }


    /**
     * 获取图片缓存目录
     *
     * @return 创建失败, 返回""
     */
    public static String getImageCachePath(Context context) {
        String path = createDir(createCacheRootPath(context) + File.separator + "img"
                + File.separator);
        return path;
    }

    /**
     * 获取图片裁剪缓存目录
     *
     * @return 创建失败, 返回""
     */
    public static String getImageCropCachePath(Context context) {
        String path = createDir(createCacheRootPath(context) + File.separator + "imgCrop"
                + File.separator);

        return path;
    }


    /**
     *  根据Uri获取文件真实地址
     */
    public static String getRealFilePath(Context context, Uri uri) {
        if (null == uri) return null;
        final String scheme = uri.getScheme();
        String realPath = null;
        if (scheme == null)
            realPath = uri.getPath();
        else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            realPath = uri.getPath();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            Cursor cursor = context.getContentResolver().query(uri,
                    new String[]{MediaStore.Images.ImageColumns.DATA},
                    null, null, null);
            if (null != cursor) {
                if (cursor.moveToFirst()) {
                    int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                    if (index > -1) {
                        realPath = cursor.getString(index);
                    }
                }
                cursor.close();
            }
        }
        if (TextUtils.isEmpty(realPath)) {
            if (uri != null) {
                String uriString = uri.toString();
                int index = uriString.lastIndexOf("/");
                String imageName = uriString.substring(index);
                File storageDir;

                storageDir = Environment.getExternalStoragePublicDirectory(
                        Environment.DIRECTORY_PICTURES);
                File file = new File(storageDir, imageName);
                if (file.exists()) {
                    realPath = file.getAbsolutePath();
                } else {
                    storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                    File file1 = new File(storageDir, imageName);
                    realPath = file1.getAbsolutePath();
                }
            }
        }
        return realPath;
    }


    /**
     * <H1>保存图片到sd卡</H1>
     * <BR>
     *
     * @param bitmap
     * @param filepath
     * @param filename
     */
    public static void saveImageToSDCard(Bitmap bitmap, String filepath, String filename) {
        File file = new File(filepath);
        if (!file.exists()) {
            file.mkdirs();
        }
        File imageFile = new File(file, filename);
        if (imageFile.exists()) {
            final File to = new File(imageFile.getAbsolutePath() + System.currentTimeMillis());
            imageFile.renameTo(to);
            to.delete();
            imageFile = new File(file, filename);
        }
        try {

            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(imageFile));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bos);
            bos.flush();
            bos.close();

            System.gc();
            System.runFinalization();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * <H1>复制文件</H1>
     * <BR>
     *
     * @param oldPath
     * @param newPath
     */
    public static void copyFile(String oldPath, String newPath) {
        try {
            FileInputStream in = new java.io.FileInputStream(oldPath);
            FileOutputStream out = new FileOutputStream(newPath);
            byte[] bt = new byte[1024];
            int count;
            while ((count = in.read(bt)) > 0) {
                out.write(bt, 0, count);
            }
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 调用此方法自动计算指定文件或指定文件夹的大小
     *
     * @param filePath 文件路径
     * @return 计算好的带B、KB、MB、GB的字符串
     */
    public static long getAutoFileOrFilesSize(String filePath) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            blockSize = getFileSize(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return blockSize;
    }

    /**
     * 获取指定文件大小
     *
     * @param file
     * @return
     * @throws Exception
     */
    private static long getFileSize(File file) throws Exception {
        long size = 0;
        FileInputStream fis = null;
        try {
            if (file.exists()) {
                fis = new FileInputStream(file);
                size = fis.available();
            } else {
                file.createNewFile();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != fis) {
                fis.close();
            }
        }

        return size;
    }

    /**
     * 转换文件大小 long-String
     *
     * @param fileS
     * @return
     */
    public static String FormatFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * 转换文件大小String-double
     *
     * @param size
     * @return
     */
    public static double FormatFileSize(String size) {
        double fileSize = 0l;
        double sizeNum = 0;
        if (size.contains("KB")) {
            sizeNum = Float.parseFloat(size.replace("KB", ""));
            fileSize = 1024 * sizeNum;
        } else if (size.contains("MB")) {
            sizeNum = Float.parseFloat(size.replace("MB", ""));
            fileSize = 1048576 * sizeNum;
        } else if (size.contains("GB")) {
            sizeNum = Float.parseFloat(size.replace("GB", ""));
            fileSize = 1073741824 * sizeNum;
        } else {
            sizeNum = Float.parseFloat(size.replace("B", ""));
            fileSize = sizeNum;
        }
        return fileSize;
    }

    /**
     * <H1>格式化文件大小（字节--MB等）</H1>
     * <BR>
     *
     * @param size
     * @return
     */
    public static String formatFileSize(String size) {
        int fileSize = 0;
        try {
            fileSize = Integer.parseInt(size);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return FormatFileSize(fileSize);
    }

    /**
     * 获取文件夹大小(递归)
     *
     * @param file File实例
     * @return long
     */
    public static long getFolderSize(java.io.File file) {

        long size = 0;
        try {
            java.io.File[] fileList = file.listFiles();
            for (int i = 0; i < fileList.length; i++) {
                if (fileList[i].isDirectory()) {
                    size = size + getFolderSize(fileList[i]);

                } else {
                    size = size + fileList[i].length();

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }
}
